﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using spotnumbers.Model;

namespace spotnumbers.Controller
{
    public class NumberFactory
    {
        private const int MAX_GEN = 1000;
        private static Random rand = new Random();

        /// <summary>
        /// Randomly generate a list of Numbers
        /// </summary>
        /// <returns>
        /// Not null
        /// </returns>
        public static List<Number> createNumbers(double width, double height, double margin, double radius, double minDistance, int maxNumber)
        {
            Debug.WriteLine("Generate Numbers...");
            List<Number> numbers = new List<Number>();
            for (int i = 0; i < maxNumber; i++)
            {
                double x, y;
                x = y = 0;
                int nGen = 0;
                bool found = false;
                while (!found && nGen < MAX_GEN)
                {
                    // generate new point
                    x = rand.NextDouble() * (width - 2 * radius - 2 * margin) + radius + margin;
                    y = rand.NextDouble() * (height - 2 * radius - 2 * margin) + radius + margin;

                    // check
                    found = true;
                    // does it overlapp

                    // new point must not overlap previous points
                    if (i > 0)
                    {
                        for (int j = 0; j < i && found; j++)
                        {
                            Number old = numbers[j];
                            float distance = (float)Math.Sqrt((Math.Pow(
                                    old.X - x, 2.0) + Math.Pow(old.Y
                                    - y, 2.0)));
                            if (distance < minDistance)
                            {
                                found = false;
                            }
                        }
                    }

                    ++nGen;
                }

                if (!found)
                {
                    Debug.WriteLine("Cannot allocate more number");
                    break;
                }
                else
                {
                    if (nGen > 100)
                        Debug.WriteLine("Found number after nGen=" + nGen);
                }

                double rotate = rand.NextDouble() * 360;
                // it's very confuse if we rotate 6 and 9
                if ((i + 1) % 6 == 0 || (i + 1) % 9 == 0)
                    rotate = 0;
                double rotateVelocity = rand.Next() % 2 == 0 ? 1.0f : -1.0f; 

                Number number = new Number() { Id = i, Text = (i+1).ToString(), X = x, Y = y, Rotate = rotate, RotateVelocity = rotateVelocity };
                numbers.Add(number);
            }
            Debug.WriteLine("Done Init. Nb of Number:" + numbers.Count());
            return numbers;
        }
    }

}
